﻿using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;

namespace Brain
{
    public class BrainModel
    {
        public BrainModelMesh[] Meshes;

        public BrainModel()
        {
        }

#if !MONOGAME
        public static void Write(Stream stream, Vector3[] vertices, int[] indices)
        {
            using (BinaryWriter writer = new BinaryWriter(stream))
            {
                writer.Write(new char[] { 'B', 'R', 'A', 'I', 'N', });

                writer.Write((int)1);

                writer.Write(vertices.Length);
                for (int x = 0; x < vertices.Length; x++)
                {
                    Vector3 v = vertices[x];
                    writer.Write(v.X);
                    writer.Write(v.Y);
                    writer.Write(v.Z);
                }

                writer.Write(indices != null);
                if (indices != null)
                {
                    writer.Write((int)IndexElementSize.ThirtyTwoBits);

                    writer.Write(indices.Length);

                    for (int x = 0; x < indices.Length; x++)
                    {
                        int k = indices[x];
                        writer.Write(k);
                    }
                }
            }
        }
#endif


        public static BrainModel Read(Stream stream)
        {
            using (BinaryReader reader = new BinaryReader(stream))
            {
                char[] buffer = new char[5];
                reader.Read(buffer, 0, 5);

                // Look for the start STAIRS chars
                if (buffer[0] != 'B' || buffer[1] != 'R' ||
                    buffer[2] != 'A' || buffer[3] != 'I' ||
                    buffer[4] != 'N')
                {
                    throw new Exception("Serialization file was not serialized by Stairs Engine");
                }

                BrainModel model = new BrainModel();

                int meshes = reader.ReadInt32();

                model.Meshes = new BrainModelMesh[meshes];
                for (int i = 0; i < meshes; i++)
                {
                    BrainModelMesh mesh = new BrainModelMesh();
                    model.Meshes[i] = mesh;

                    int data = reader.ReadInt32();
                    Vector3[] vertices = new Vector3[data];

                    for (int x = 0; x < data; x++)
                    {
                        float X = reader.ReadSingle();
                        float Y = reader.ReadSingle();
                        float Z = reader.ReadSingle();
                        vertices[x] = new Vector3(X, Y, Z);
                    }

                    VertexPositionTexture[] ver = new VertexPositionTexture[data];
                    for (int x = 0; x < ver.Length; x++)
                    {
                        ver[x].Position = vertices[x];
                    }

                    mesh.VertexBuffer = new VertexBuffer(Engine.Instance.GraphicsDevice, typeof(VertexPositionTexture), ver.Length,
                        BufferUsage.None);
                    mesh.VertexBuffer.SetData(ver);

                    bool index = reader.ReadBoolean();
                    if (index)
                    {
                        IndexElementSize ind = (IndexElementSize)reader.ReadInt32();

                        if (ind == IndexElementSize.SixteenBits)
                        {
                            int h = reader.ReadInt32();

                            short[] el = new short[h];
                            for (int x = 0; x < h; x++)
                            {
                                short k = reader.ReadInt16();
                                el[x] = k;
                            }

#if MONOGAME
                            mesh.IndexBuffer = new IndexBuffer(Engine.Instance.GraphicsDevice,
                                IndexElementSize.SixteenBits, h, BufferUsage.None);
#else
                            mesh.IndexBuffer = new IndexBuffer(Engine.Instance.GraphicsDevice,
                                ind, h, BufferUsage.None);
#endif
                            mesh.IndexBuffer.SetData(el);
                        }
                        else if (ind == IndexElementSize.ThirtyTwoBits)
                        {
                            int h = reader.ReadInt32();

                            uint[] el = new uint[h];
                            for (int x = 0; x < h; x++)
                            {
                                uint k = (uint)reader.ReadInt32();
                                el[x] = k;
                            }

#if MONOGAME
                            mesh.IndexBuffer = new IndexBuffer(Engine.Instance.GraphicsDevice,
                                IndexElementSize.ThirtyTwoBits, h, BufferUsage.None);
#else
                            mesh.IndexBuffer = new IndexBuffer(Engine.Instance.GraphicsDevice,
                                ind, h, BufferUsage.None);
#endif
                            mesh.IndexBuffer.SetData(el);
                        }
                    }
                }


                return model;
            }
        }

    }
}
